%%%-------------------------------------------------------------------
%% @doc utils public API
%% 常用函数集
%% @end
%%%-------------------------------------------------------------------

-module(utils).


-export([ md5/1
        , timestamp/0
        ]).
-export([ to_atom/1
        , to_list/1
        , to_binary/1
        , to_int/1
        , to_bool/1
        , to_tuple/1
        ]).
-export([ code_to_string/1
        , string_to_code/1
        ]).


%%%-------------------------------------------------------------------
%% @doc md5
md5(Str) ->
    Md5 = erlang:md5(Str),
    lists:flatten([io_lib:format("~2.16.0b", [D]) || D <- binary_to_list(Md5)]).

%% @doc unix timestamp
timestamp() ->
    erlang:system_time(second).


%%%-------------------------------------------------------------------
%% @doc convert other type to atom
to_atom(Msg) when is_atom(Msg)      -> Msg;
to_atom(Msg) when is_binary(Msg)    -> list_to_atom( binary_to_list(Msg) );
to_atom(Msg) when is_list(Msg)      -> list_to_atom(Msg);
to_atom(_) -> throw(other_value).

%% @doc convert other type to list
to_list(Msg) when is_list(Msg)      -> Msg;
to_list(Msg) when is_binary(Msg)    -> binary_to_list(Msg);
to_list(Msg) when is_atom(Msg)      -> atom_to_list(Msg);
to_list(Msg) when is_integer(Msg)   -> integer_to_list(Msg);
to_list(Msg) when is_tuple(Msg)     -> tuple_to_list(Msg);
to_list(_) -> throw(other_value).

%% @doc convert other type to binary
to_binary(Msg) when is_binary(Msg)  -> Msg;
to_binary(Msg) when is_atom(Msg)    -> list_to_binary( atom_to_list(Msg) );
to_binary(Msg) when is_list(Msg)    -> list_to_binary(Msg);
to_binary(Msg) when is_integer(Msg) -> list_to_binary( integer_to_list(Msg) );
to_binary(_) -> throw(other_value).

%% @doc convert other type to integer
to_int(Msg) when is_integer(Msg)    -> Msg;
to_int(Msg) when is_binary(Msg)     -> list_to_integer( binary_to_list(Msg) );
to_int(Msg) when is_list(Msg)       -> list_to_integer(Msg);
to_int(Msg) when is_float(Msg)      -> round(Msg);
to_int(_) -> throw(other_value).

%% @doc convert other type to bool
to_bool(D) when is_boolean(D)       -> D;
to_bool(D) when is_integer(D)       -> D =/= 0;
to_bool(D) when is_list(D)          -> length(D) =/= 0;
to_bool(D) when is_binary(D)        -> to_bool( binary_to_list(D) );
to_bool(_) -> throw(other_value).

%% @doc convert other type to tuple
to_tuple(T) when is_tuple(T)        -> T;
to_tuple(T) when is_list(T)         -> list_to_tuple(T);
to_tuple(T) -> {T}.


%%%-------------------------------------------------------------------
%% @doc Transform code to string
code_to_string(Term) ->
    lists:flatten( io_lib:write( Term ) ).

%% @doc Transform string to code
string_to_code(String) ->
    {ok, T, _} = erl_scan:string(String++"."),
    {ok, Term} = erl_parse:parse_term(T),
    Term.


